﻿using System;
using System.Linq;
using IterationLife.Extensions.Sms;
using IterationLife.System.Constants;
using IterationLife.System.ExternalIdentity;
using IterationLife.System.Models;
using IterationLife.System.Repositories;
using IterationLife.System.Tools;
using Util;
using Util.Exceptions;

namespace IterationLife.System.Services
{
    public class UserManager : IUserManager
    {


        protected internal IUserRepository UserRepository { get; set; }
        protected internal IExternalUserBindingRepository ExternalUserBindingRepository { get; set; }

        public IVerificationCodeManager VerificationCodeManager { get; set; }

        public ISmsSender SmsSender { get; set; }
        public UserManager(IUserRepository repository, IExternalUserBindingRepository externalUserBindingRepository, IVerificationCodeManager verificationCodeManager, ISmsSender smsSender)
        {
            UserRepository = repository;
            ExternalUserBindingRepository = externalUserBindingRepository;
            VerificationCodeManager = verificationCodeManager;
            SmsSender = smsSender;
        }

        public bool ChangeEmail(User user, string newEmail, string token)
        {
            throw new NotImplementedException();
        }

        public bool ChangePassword(User user, string currentPassword, string newPassword)
        {
            throw new NotImplementedException();
        }

        public bool ChangePasswordByToken(User user, string newPassword, string token)
        {
            throw new NotImplementedException();
        }

        public bool ChangePhoneNumber(User user, string newPhoneNumber, string token)
        {
            throw new NotImplementedException();
        }



        public bool CheckUserNameExists(string username)
        {
            throw new NotImplementedException();
        }

        public void SendRegisterCode(string phone)
        {
            var code = VerificationCodeManager.GenerateCode(phone, VerificationPurpose.RegisterUserPurpose);
            string smsMessage = $"注册验证码：{code}";
            SmsSender.SendSms(phone, smsMessage);
        }

        public User Register(string username, string password, string phone = null, string verifyCode = null)
        {
            ValidateRegisterInfo(username, password, phone, verifyCode);
            var user = new User(Guid.NewGuid())
            {
                UserName = username,
                Mobile = phone,
            };
            user.InitUser();
            user.Password = PasswordHashHelper.HashPassword(password, user.Id.ToString());
            UserRepository.Add(user);
            return user;
        }

        private void ValidateRegisterInfo(string username, string password, string phone, string verifyCode)
        {
            if (string.IsNullOrWhiteSpace(username))
                throw new Warning("用户名不能为空");
            if (UserRepository.IsUserNameExisted(username))
                throw new Warning("用户名已存在");
            if (!string.IsNullOrWhiteSpace(phone))
            {
                //todo,手机格式校验
                if (UserRepository.IsPhoneNumberExisted(phone))
                    throw new Warning("手机号已存在");
                VerificationCodeManager.CheckCode(phone, VerificationPurpose.RegisterUserPurpose, verifyCode);
            }
            if (string.IsNullOrWhiteSpace(password))
                throw new Warning("密码不能为空");
        }

        public void CreateUserByUserInfo(string provider, ExternalUserInfo userInfo)
        {
            throw new NotImplementedException();
        }

        public void Delete(User user)
        {
            throw new NotImplementedException();
        }

        public User FindUserByAccount(string account)
        {
            return UserRepository.Find().SingleOrDefault(d => d.UserName == account || d.Mobile == account || d.Email == account);
        }

        public User FindUserByExternalLogin(string loginProvider, string externalId)
        {
            throw new NotImplementedException();
        }

        public bool VerifyPassword(User user, string password)
        {
            return user.Password == PasswordHashHelper.HashPassword(password, user.Id.ToString());
        }

        public void SendGetBackPasswordCode(string phone)
        {
            var code = VerificationCodeManager.GenerateCode(phone, VerificationPurpose.GetBackPasswordPurpose);
            string smsMessage = $"找回密码验证码：{code}";
            SmsSender.SendSms(phone, smsMessage);
        }

        public void GetBackPassword(string phone, string newPassword, string verifyCode)
        {
            if (string.IsNullOrWhiteSpace(newPassword))
                throw new Warning("密码不能为空");
            var user = UserRepository.Single(d => d.Mobile == phone);
            if (user == null)
                throw new Warning("该手机号没有绑定的用户");
            VerificationCodeManager.CheckCode(phone, VerificationPurpose.GetBackPasswordPurpose, verifyCode);
            user.Password = PasswordHashHelper.HashPassword(newPassword, user.Id.ToString());
        }

        public void AddExternalUser(Guid userId, string externalUserId, string externalCode)
        {
            var user = UserRepository.Single(d => d.Id == userId);
            if (user == null)
                throw new Warning("用户不存在");
            if(externalUserId.IsEmpty())
                throw new Warning("绑定账号Id不能为空");
            bool isBinded=ExternalUserBindingRepository.Find().Any(d => d.UserId == userId && d.ExternalCode == externalCode);
            if(isBinded)
                throw new Warning("用户已经绑定过账号");
            ExternalUserBindingRepository.Add(new ExternalUserBinding(Guid.NewGuid())
            {
                UserId = userId,
                ExternalUserId = externalUserId,
                ExternalCode = externalCode,
                CreationTime = DateTime.Now
            });
        }
    }
}
